﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Threading.Tasks;
using ERP.ERPModels.Production.MasterData;
using ERP.ERPModels.Production.ProductionManagement;
using ERP.ERPModels.RepositoryManage;
using ERP.ProductionManage.Dtos;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
using Volo.Abp.Domain.Repositories;

namespace ERP.ProductionManage
{
    /// <summary>
    /// 客户订单服务实现
    /// </summary>
    public class CustomerOrderService : ApplicationService, ICustomerOrderService
    {
        private readonly IRepository<CustomerOrders, int> _customerOrderRepository;
        private readonly IRepository<CustomerOrdersDetail, int> _customerOrderDetailRepository;
        private readonly IRepository<Material, int> _materialRepository;
        private readonly IRepository<Inventory, int> _inventoryRepository;
        private readonly IRepository<Customers, int> _customerRepository;
        private readonly ILogger<CustomerOrderService> _logger;

        public CustomerOrderService(
            IRepository<CustomerOrders, int> customerOrderRepository,
            IRepository<CustomerOrdersDetail, int> customerOrderDetailRepository,
            IRepository<Material, int> materialRepository,
            IRepository<Inventory, int> inventoryRepository,
            IRepository<Customers, int> customerRepository,
            ILogger<CustomerOrderService> logger)
        {
            _customerOrderRepository = customerOrderRepository;
            _customerOrderDetailRepository = customerOrderDetailRepository;
            _materialRepository = materialRepository;
            _inventoryRepository = inventoryRepository;
            _customerRepository = customerRepository;
            _logger = logger;
        }

        /// <summary>
        /// 获取客户订单分页列表
        /// </summary>
        public async Task<PagedResultDto<CustomerOrderDto>> GetListAsync(GetCustomerOrderInputDto input)
        {
            var query = await _customerOrderRepository.GetQueryableAsync();

            // 应用筛选条件
            if (!string.IsNullOrWhiteSpace(input.OrderCode))
            {
                query = query.Where(x => x.OrderCode.Contains(input.OrderCode));
            }

            if (!string.IsNullOrWhiteSpace(input.CustomerName))
            {
                query = query.Where(x => x.CustomerName.Contains(input.CustomerName));
            }

            if (input.OrderDateStart.HasValue)
            {
                query = query.Where(x => x.OrderDate >= input.OrderDateStart.Value);
            }

            if (input.OrderDateEnd.HasValue)
            {
                query = query.Where(x => x.OrderDate <= input.OrderDateEnd.Value);
            }

            if (input.DeliveryDateStart.HasValue)
            {
                query = query.Where(x => x.DeliveryDate >= input.DeliveryDateStart.Value);
            }

            if (input.DeliveryDateEnd.HasValue)
            {
                query = query.Where(x => x.DeliveryDate <= input.DeliveryDateEnd.Value);
            }

            if (input.OrderStatus.HasValue)
            {
                query = query.Where(x => x.OrderStatus == input.OrderStatus.Value);
            }

            // 排序
            if (!string.IsNullOrWhiteSpace(input.Sorting))
            {
                query = query.OrderBy(input.Sorting);
            }
            else
            {
                query = query.OrderByDescending(x => x.Id);
            }

            // 分页
            var totalCount = await query.CountAsync();
            var items = await query
                .Skip(input.SkipCount)
                .Take(input.MaxResultCount)
                .ToListAsync();

            var dtos = items.Select(MapToDto).ToList();

            return new PagedResultDto<CustomerOrderDto>(totalCount, dtos);
        }

        /// <summary>
        /// 获取客户订单详情
        /// </summary>
        public async Task<CustomerOrderDto> GetAsync(int id)
        {
            var entity = await _customerOrderRepository.GetAsync(id);
            var dto = MapToDto(entity);

            // 获取订单详情
            dto.Details = await GetOrderDetailsAsync(id);

            return dto;
        }

        /// <summary>
        /// 创建客户订单
        /// </summary>
        public async Task<CustomerOrderDto> CreateAsync(CreateCustomerOrderDto input)
        {
            var entity = new CustomerOrders
            {
                OrderCode = input.OrderCode,
                ProductCode = input.ProductCode,
                CustomerCode = input.CustomerCode,
                CustomerName = input.CustomerName,
                OrderDate = input.OrderDate,
                DeliveryDate = input.DeliveryDate,
                Specification = input.Specification,
                Quantity = input.Quantity,
                Unit = input.Unit,
                OrderStatus = 0, // 默认为草稿状态
                QualityRequirements = input.QualityRequirements
            };

            entity = await _customerOrderRepository.InsertAsync(entity, true);
            _logger.LogInformation("创建客户订单成功，ID: {Id}, 订单编码: {OrderCode}", entity.Id, entity.OrderCode);

            return MapToDto(entity);
        }

        /// <summary>
        /// 更新客户订单
        /// </summary>
        public async Task<CustomerOrderDto> UpdateAsync(int id, UpdateCustomerOrderDto input)
        {
            var entity = await _customerOrderRepository.GetAsync(id);

            entity.OrderCode = input.OrderCode;
            entity.ProductCode = input.ProductCode;
            entity.CustomerCode = input.CustomerCode;
            entity.CustomerName = input.CustomerName;
            entity.OrderDate = input.OrderDate;
            entity.DeliveryDate = input.DeliveryDate;
            entity.Specification = input.Specification;
            entity.Quantity = input.Quantity;
            entity.Unit = input.Unit;
            entity.QualityRequirements = input.QualityRequirements;

            entity = await _customerOrderRepository.UpdateAsync(entity, true);
            _logger.LogInformation("更新客户订单成功，ID: {Id}, 订单编码: {OrderCode}", entity.Id, entity.OrderCode);

            return MapToDto(entity);
        }

        /// <summary>
        /// 删除客户订单
        /// </summary>
        public async Task DeleteAsync(int id)
        {
            // 先删除订单详情
            var details = await _customerOrderDetailRepository.GetListAsync(x => x.CustomerOrderId == id);
            foreach (var detail in details)
            {
                await _customerOrderDetailRepository.DeleteAsync(detail.Id);
            }

            // 删除订单
            await _customerOrderRepository.DeleteAsync(id);
            _logger.LogInformation("删除客户订单成功，ID: {Id}", id);
        }

        /// <summary>
        /// 生成订单编码
        /// </summary>
        public async Task<string> GenerateOrderCodeAsync()
        {
            var today = DateTime.Now.ToString("yyyyMMdd");
            var prefix = $"CO{today}";

            var query = await _customerOrderRepository.GetQueryableAsync();
            var maxCode = await query
                .Where(x => x.OrderCode.StartsWith(prefix))
                .Select(x => x.OrderCode)
                .OrderByDescending(x => x)
                .FirstOrDefaultAsync();

            var sequence = 1;
            if (!string.IsNullOrEmpty(maxCode) && maxCode.Length > prefix.Length)
            {
                var sequenceStr = maxCode.Substring(prefix.Length);
                if (int.TryParse(sequenceStr, out var lastSequence))
                {
                    sequence = lastSequence + 1;
                }
            }

            return $"{prefix}{sequence:D4}";
        }

        /// <summary>
        /// 获取可选择的物料列表（只包含物料，不包含产品）
        /// </summary>
        public async Task<List<MaterialSelectDto>> GetMaterialsForSelectAsync()
        {
            var query = await _materialRepository.GetQueryableAsync();
            var inventoryQuery = await _inventoryRepository.GetQueryableAsync();

            // 只获取物料（MaterielTypePid = 0）
            var materials = await query
                .Where(x => x.MaterielTypePid == 0 && x.IsNo == 1)
                .ToListAsync();

            var result = new List<MaterialSelectDto>();

            foreach (var material in materials)
            {
                // 获取库存数量
                var stockQuantity = await inventoryQuery
                    .Where(x => x.ProductItem == material.MaterielCode)
                    .SumAsync(x => x.GalleryNumber);

                result.Add(new MaterialSelectDto
                {
                    Id = material.Id,
                    MaterielName = material.MaterielName,
                    MaterielCode = material.MaterielCode,
                    Specifications = material.Specifications,
                    UnitsId = material.UnitsId,
                    StockQuantity = stockQuantity
                });
            }

            return result.OrderBy(x => x.MaterielCode).ToList();
        }

        /// <summary>
        /// 添加订单详情
        /// </summary>
        public async Task<CustomerOrderDetailDto> CreateOrderDetailAsync(CreateCustomerOrderDetailDto input)
        {
            var entity = new CustomerOrdersDetail
            {
                CustomerOrderId = input.CustomerOrderId,
                MaterialId = input.MaterialId,
                Num = input.Num,
                Size = input.Size
            };

            entity = await _customerOrderDetailRepository.InsertAsync(entity, true);
            _logger.LogInformation("添加订单详情成功，ID: {Id}, 订单ID: {CustomerOrderId}, 物料ID: {MaterialId}", 
                entity.Id, entity.CustomerOrderId, entity.MaterialId);

            return await MapToDetailDto(entity);
        }

        /// <summary>
        /// 更新订单详情
        /// </summary>
        public async Task<CustomerOrderDetailDto> UpdateOrderDetailAsync(int detailId, UpdateCustomerOrderDetailDto input)
        {
            var entity = await _customerOrderDetailRepository.GetAsync(detailId);
            
            entity.Num = input.Num;
            
            entity = await _customerOrderDetailRepository.UpdateAsync(entity, true);
            _logger.LogInformation("更新订单详情成功，ID: {Id}, 新需求数量: {Num}", entity.Id, entity.Num);

            return await MapToDetailDto(entity);
        }

        /// <summary>
        /// 删除订单详情
        /// </summary>
        public async Task DeleteOrderDetailAsync(int detailId)
        {
            await _customerOrderDetailRepository.DeleteAsync(detailId);
            _logger.LogInformation("删除订单详情成功，ID: {Id}", detailId);
        }

        /// <summary>
        /// 获取订单详情列表
        /// </summary>
        public async Task<List<CustomerOrderDetailDto>> GetOrderDetailsAsync(int customerOrderId)
        {
            var details = await _customerOrderDetailRepository.GetListAsync(x => x.CustomerOrderId == customerOrderId);
            var result = new List<CustomerOrderDetailDto>();

            foreach (var detail in details)
            {
                result.Add(await MapToDetailDto(detail));
            }

            return result;
        }

        /// <summary>
        /// 生成生产工单
        /// </summary>
        public async Task GenerateProductionOrderAsync(int customerOrderId)
        {
            var order = await _customerOrderRepository.GetAsync(customerOrderId);
            var details = await _customerOrderDetailRepository.GetListAsync(x => x.CustomerOrderId == customerOrderId);

            if (!details.Any())
            {
                throw new InvalidOperationException("订单没有物料需求，无法生成生产工单");
            }

            // 更新订单状态为已生成生产工单
            order.OrderStatus = 1;
            await _customerOrderRepository.UpdateAsync(order);

            _logger.LogInformation("生成生产工单成功，订单ID: {CustomerOrderId}", customerOrderId);
        }

        /// <summary>
        /// 映射到DTO
        /// </summary>
        private CustomerOrderDto MapToDto(CustomerOrders entity)
        {
            return new CustomerOrderDto
            {
                Id = entity.Id,
                OrderCode = entity.OrderCode,
                ProductCode = entity.ProductCode,
                CustomerCode = entity.CustomerCode,
                CustomerName = entity.CustomerName,
                OrderDate = entity.OrderDate,
                DeliveryDate = entity.DeliveryDate,
                Specification = entity.Specification,
                Quantity = entity.Quantity,
                Unit = entity.Unit,
                OrderStatus = entity.OrderStatus,
                OrderStatusText = entity.OrderStatus == 0 ? "草稿" : "已生成生产工单",
                QualityRequirements = entity.QualityRequirements
            };
        }

        /// <summary>
        /// 映射详情到DTO
        /// </summary>
        private async Task<CustomerOrderDetailDto> MapToDetailDto(CustomerOrdersDetail entity)
        {
            var material = await _materialRepository.GetAsync(entity.MaterialId);
            var inventoryQuery = await _inventoryRepository.GetQueryableAsync();
            var stockQuantity = await inventoryQuery
                .Where(x => x.ProductItem == material.MaterielCode)
                .SumAsync(x => x.GalleryNumber);

            return new CustomerOrderDetailDto
            {
                Id = entity.Id,
                CustomerOrderId = entity.CustomerOrderId,
                MaterialId = entity.MaterialId,
                MaterialName = material.MaterielName,
                MaterialCode = material.MaterielCode,
                Num = entity.Num,
                Size = entity.Size,
                Unit = material.UnitsId,
                StockQuantity = stockQuantity
            };
        }

        /// <summary>
        /// 导出客户订单
        /// </summary>
        public async Task<byte[]> ExportAsync(GetCustomerOrderInputDto input)
        {
            var query = await _customerOrderRepository.GetQueryableAsync();

            // 应用筛选条件
            if (!string.IsNullOrWhiteSpace(input.OrderCode))
            {
                query = query.Where(x => x.OrderCode.Contains(input.OrderCode));
            }

            if (!string.IsNullOrWhiteSpace(input.CustomerName))
            {
                query = query.Where(x => x.CustomerName.Contains(input.CustomerName));
            }

            if (input.OrderDateStart.HasValue)
            {
                query = query.Where(x => x.OrderDate >= input.OrderDateStart.Value);
            }

            if (input.OrderDateEnd.HasValue)
            {
                query = query.Where(x => x.OrderDate <= input.OrderDateEnd.Value);
            }

            if (input.DeliveryDateStart.HasValue)
            {
                query = query.Where(x => x.DeliveryDate >= input.DeliveryDateStart.Value);
            }

            if (input.DeliveryDateEnd.HasValue)
            {
                query = query.Where(x => x.DeliveryDate <= input.DeliveryDateEnd.Value);
            }

            if (input.OrderStatus.HasValue)
            {
                query = query.Where(x => x.OrderStatus == input.OrderStatus.Value);
            }

            // 排序
            if (!string.IsNullOrWhiteSpace(input.Sorting))
            {
                query = query.OrderBy(input.Sorting);
            }
            else
            {
                query = query.OrderByDescending(x => x.Id);
            }

            var items = await query.ToListAsync();

            using var ms = new MemoryStream();
            IWorkbook workbook = new XSSFWorkbook();
            ISheet sheet = workbook.CreateSheet("客户订单");

            // 创建表头
            var headerRow = sheet.CreateRow(0);
            headerRow.CreateCell(0).SetCellValue("订单编码");
            headerRow.CreateCell(1).SetCellValue("产品编码");
            headerRow.CreateCell(2).SetCellValue("客户编码");
            headerRow.CreateCell(3).SetCellValue("客户名称");
            headerRow.CreateCell(4).SetCellValue("订货日期");
            headerRow.CreateCell(5).SetCellValue("交货日期");
            headerRow.CreateCell(6).SetCellValue("规格型号");
            headerRow.CreateCell(7).SetCellValue("订货数量");
            headerRow.CreateCell(8).SetCellValue("计量单位");
            headerRow.CreateCell(9).SetCellValue("订单状态");
            headerRow.CreateCell(10).SetCellValue("质量要求");

            // 填充数据
            for (int i = 0; i < items.Count; i++)
            {
                var item = items[i];
                var row = sheet.CreateRow(i + 1);
                row.CreateCell(0).SetCellValue(item.OrderCode ?? "");
                row.CreateCell(1).SetCellValue(item.ProductCode ?? "");
                row.CreateCell(2).SetCellValue(item.CustomerCode ?? "");
                row.CreateCell(3).SetCellValue(item.CustomerName ?? "");
                row.CreateCell(4).SetCellValue(item.OrderDate.ToString("yyyy-MM-dd"));
                row.CreateCell(5).SetCellValue(item.DeliveryDate.ToString("yyyy-MM-dd"));
                row.CreateCell(6).SetCellValue(item.Specification ?? "");
                row.CreateCell(7).SetCellValue(item.Quantity);
                row.CreateCell(8).SetCellValue(item.Unit ?? "");
                row.CreateCell(9).SetCellValue(item.OrderStatus == 0 ? "草稿" : "已生成生产工单");
                row.CreateCell(10).SetCellValue(item.QualityRequirements ?? "");
            }

            // 自适应列宽
            for (int i = 0; i < 11; i++)
            {
                sheet.AutoSizeColumn(i);
            }

            workbook.Write(ms);
            return ms.ToArray();
        }

        /// <summary>
        /// 获取产品选择列表
        /// </summary>
        public async Task<PagedResultDto<ProductSelectDto>> GetProductsForSelectAsync(GetProductSelectInputDto input)
        {
            var query = await _materialRepository.GetQueryableAsync();

            // 只获取产品（MaterielTypePid = 1）
            query = query.Where(x => x.MaterielTypePid == 1 && x.IsNo == 1);

            // 应用筛选条件
            if (!string.IsNullOrWhiteSpace(input.Keyword))
            {
                query = query.Where(x => 
                    x.MaterielCode.Contains(input.Keyword) ||
                    x.MaterielName.Contains(input.Keyword) ||
                    x.Specifications.Contains(input.Keyword));
            }

            if (!string.IsNullOrWhiteSpace(input.MaterielCode))
            {
                query = query.Where(x => x.MaterielCode.Contains(input.MaterielCode));
            }

            if (!string.IsNullOrWhiteSpace(input.MaterielName))
            {
                query = query.Where(x => x.MaterielName.Contains(input.MaterielName));
            }

            // 排序
            if (!string.IsNullOrWhiteSpace(input.Sorting))
            {
                query = query.OrderBy(input.Sorting);
            }
            else
            {
                query = query.OrderBy(x => x.MaterielCode);
            }

            // 分页
            var totalCount = await query.CountAsync();
            var items = await query
                .Skip(input.SkipCount)
                .Take(input.MaxResultCount)
                .ToListAsync();

            var dtos = items.Select(x => new ProductSelectDto
            {
                Id = x.Id,
                MaterielName = x.MaterielName,
                MaterielCode = x.MaterielCode,
                Specifications = x.Specifications,
                UnitsId = x.UnitsId
            }).ToList();

            return new PagedResultDto<ProductSelectDto>(totalCount, dtos);
        }

        /// <summary>
        /// 获取客户选择列表
        /// </summary>
        public async Task<PagedResultDto<CustomerSelectDto>> GetCustomersForSelectAsync(GetCustomerSelectInputDto input)
        {
            var query = await _customerRepository.GetQueryableAsync();

            // 只获取有效客户
            query = query.Where(x => x.IsNo == 1);

            // 应用筛选条件
            if (!string.IsNullOrWhiteSpace(input.Keyword))
            {
                query = query.Where(x => 
                    x.CustomerCode.Contains(input.Keyword) ||
                    x.CustomerName.Contains(input.Keyword));
            }

            if (!string.IsNullOrWhiteSpace(input.CustomerCode))
            {
                query = query.Where(x => x.CustomerCode.Contains(input.CustomerCode));
            }

            if (!string.IsNullOrWhiteSpace(input.CustomerName))
            {
                query = query.Where(x => x.CustomerName.Contains(input.CustomerName));
            }

            if (!string.IsNullOrWhiteSpace(input.CustomerType))
            {
                query = query.Where(x => x.CustomerType.Contains(input.CustomerType));
            }

            // 排序
            if (!string.IsNullOrWhiteSpace(input.Sorting))
            {
                query = query.OrderBy(input.Sorting);
            }
            else
            {
                query = query.OrderBy(x => x.CustomerCode);
            }

            // 分页
            var totalCount = await query.CountAsync();
            var items = await query
                .Skip(input.SkipCount)
                .Take(input.MaxResultCount)
                .ToListAsync();

            var dtos = items.Select(x => new CustomerSelectDto
            {
                Id = x.Id,
                CustomerCode = x.CustomerCode,
                CustomerName = x.CustomerName,
                CustomerType = x.CustomerType,
                CustomerPhone = x.CustomerPhone
            }).ToList();

            return new PagedResultDto<CustomerSelectDto>(totalCount, dtos);
        }
    }
}
